import type { TableColumnCtx } from 'element-plus/es/components/table/src/table-column/defaults'
import { utils, write, writeFile } from 'xlsx'
import { saveAs } from 'file-saver'
import { get } from './lodash'

type MList = 'index' | 'newIndex' | 'num'
interface SpanMethodProps {
    row: Common.AnyKey
    column: TableColumnCtx<Common.AnyKey>
    rowIndex: number
    columnIndex: number
}
/**
 * 表格合并
 * @param data - 数据源
 * @param merge - 指定需要合并表头字段集合
 */
export function mergeTableRow(data: Array<Common.AnyKey>, merge: Array<string>) {
    if (!merge || !merge.length) {
        return data
    }
    merge.forEach((m) => {
        const mList: { [key: string]: Record<MList, number> } = {}
        data = data.map((v, index) => {
            const rowVal = v[m]
            if (mList[rowVal] && mList[rowVal].newIndex === index) {
                mList[rowVal]['num']++
                mList[rowVal]['newIndex']++
                data[mList[rowVal]['index']][m + '-span'].rowspan++
                v[m + '-span'] = {
                    rowspan: 0,
                    colspan: 0,
                }
            } else {
                mList[rowVal] = { num: 1, index: index, newIndex: index + 1 }
                v[m + '-span'] = {
                    rowspan: 1,
                    colspan: 1,
                }
            }
            return v
        })
    })
    return data
}
/**
 * 表格合并方法
 */
export function mergeSpanMethod({ row, column, rowIndex, columnIndex }: SpanMethodProps) {
    const span = column['property'] + '-span'
    if (row[span]) {
        return row[span]
    }
}
/**
 * 导出当前表数据
 * @param data - 数据源
 * @param fields - Map([ ['name': '姓名'] ])
 */
export function exportTable(data: Array<any>, fields: Map<string, string>, name: string = '导出表格') {
    const result: Array<any> = []
    const merges: Array<any> = []
    const fieldsArray = [...fields.keys()]
    data.forEach((item, key) => {
        fieldsArray.forEach((i, column) => {
            const rowspan = get(item, `${fieldsArray[column]}-span.rowspan`) > 1 ? get(item, `${fieldsArray[column]}-span.rowspan`) + key : 0
            merges.push({
                s: { c: column, r: !rowspan ? 0 : key + 1 },
                e: { c: column, r: rowspan },
            })
        })
    })
    for (let i of data) {
        const item: Common.AnyKey = {}
        for (let j in i) {
            if (fields.has(j)) {
                item[<string>fields.get(j)] = i[j]
            }
        }
        result.push(item)
    }
    let ws = utils.json_to_sheet(result)
    // 列宽
    ws['!cols'] = new Array(fields.size).fill({ wch: 30 })
    // 行高
    ws['!rows'] = new Array(data.length + 1).fill({ hpx: 30 })
    // 单元格合并
    ws['!merges'] = merges
    let wb = utils.book_new()
    utils.book_append_sheet(wb, ws, 'sheet')
    let wb_out = write(wb, { bookType: 'xlsx', type: 'array' })
    let _blob = new Blob([wb_out], { type: 'application/octet-stream;charset=utf-8' })
    saveAs(_blob, `${name}.xlsx`)
}
